#include "KernelHeap.h"
#include <stddef.h>
#include "../IO/Terminal.h"
#include "../Helpers/StringHelpers.h"
extern unsigned int endkernel;

namespace Memory{
    KernelHeap::KernelHeap(IO::Terminal *terminal){
        _terminal = terminal;
	
        unsigned int page_aligned_end = (((unsigned int)&endkernel)&0xFFFFF000)+0x1000;
        unsigned int *page_directory = (unsigned int*)page_aligned_end;

        char buffer[16];
        Helpers::StringHelpers::IntToString((uint32_t)page_directory, 16, buffer);
        *_terminal << "Page directory at: 0x" << buffer << "\nWorks here :(" << "  ...ju";
        

        for(int i = 0; i < 1024; i++)
        {
            //attribute: supervisor level, read/write, not present.
            page_directory[i] = 0 | 2; 
        }
        
        unsigned int *first_page_table = page_directory + 0x1000;

        unsigned int address = 0; 
 
        //we will fill all 1024 entries, mapping 4 megabytes
        for(int i = 0; i < 1024; i++)
        {
            first_page_table[i] = address | 3; // attributes: supervisor level, read/write, present.
            address = address + 4096; //advance the address to the next page boundary
        }

        page_directory[0] = (unsigned int)first_page_table; 
        page_directory[0] |= 3;// attributes: supervisor level, read/write, present

        asm volatile("mov %0, %%cr3":: "b"(page_directory));
        
        //reads cr0, switches the "paging enable" bit, and writes it back.
        unsigned int cr0;
        asm volatile("mov %%cr0, %0": "=b"(cr0));
        cr0 |= 0x80000000;
        asm volatile("mov %0, %%cr0":: "b"(cr0));
    }

    void* KernelHeap::Allocate(size_t sizeInBytes){
        (void)(sizeInBytes);
    	return 0;
    }
    void KernelHeap::Free(void* address){
        (void)(address);
    }
}
